import Arc from './Arc'
import Line from './Line'
import Text from './Text'
import { drawArrow } from '@/utils/common'
export default class TreeNode extends Text {
  constructor(x, y, arcX, arcY, value, key, index, color) {
    super(x, y, value, key)
    this.arc = new Arc(arcX, arcY, index, color)
    this.left = undefined
    this.right = undefined
    this.parent = undefined
  }

  draw(ctx) {
    this.setXY(this.x, this.y)
    this.arc.draw(ctx)
    super.draw(ctx)
    if (this.left) {
      drawArrow(ctx, this.x, this.y, this.arc.left.toX, this.arc.left.toY)
    }

    if (this.right) {
      drawArrow(ctx, this.x, this.y, this.arc.right.toX, this.arc.right.toY)
    }

  }

  setLeft(node) {
    this.left = node
    let { fromX, fromY, toX, toY } = this.getLineXY(this.x, this.y, 100, 100)
    this.arc.left = new Line(fromX, fromY, toX, toY)
    node.parent = this
  }

  setRight(node) {
    this.right = node
    let { fromX, fromY, toX, toY } = this.getLineXY(this.x, this.y, 100, 100)
    this.arc.right = new Line(fromX, fromY, toX, toY)
    node.parent = this
  }

  setXY(x, y) {
    this.x = this.arc.x = x
    this.y = this.arc.y = y
    if (this.arc.left) {
      let { fromX, fromY, toX, toY } = this.getLineXY(x, y, this.left.x, this.left.y)
      this.arc.left.fromX = fromX
      this.arc.left.fromY = fromY
      this.arc.left.toX = toX
      this.arc.left.toY = toY
    }

    if (this.arc.right) {
      let { fromX, fromY, toX, toY } = this.getLineXY(x, y, this.right.x, this.right.y)
      this.arc.right.fromX = fromX
      this.arc.right.fromY = fromY
      this.arc.right.toX = toX
      this.arc.right.toY = toY
    }
  }

  getLineXY(x, y, x1, y1) {
    let k = (y - y1) / (x - x1)
    let rad = Math.atan(k);

    if (x1 < x) {
      let toX = x1 + Arc.R * Math.cos(rad)
      let toY = y1 + Arc.R * Math.sin(rad)
      let fromX = x + Arc.R * Math.cos(rad + Math.PI)
      let fromY = y + Arc.R * Math.sin(rad + Math.PI)
      return { fromX, fromY, toX, toY }
    } else {
      let toX = x1 + Arc.R * Math.cos(rad + Math.PI)
      let toY = y1 + Arc.R * Math.sin(rad + Math.PI)
      let fromX = x + Arc.R * Math.cos(rad)
      let fromY = y + Arc.R * Math.sin(rad)
      return { fromX, fromY, toX, toY }
    }

  }

  deepCopy() {
    let treeNode = new TreeNode(this.x, this.y, this.arc.x, this.arc.y, this.value, this.key, this.arc.index, this.arc.color)
    let arc = treeNode.arc
    if (this.arc.left) {
      let { fromX, fromY, toX, toY } = this.arc.left
      arc.setLeft(new Line(fromX, fromY, toX, toY))
    }

    if (this.arc.right) {
      let { fromX, fromY, toX, toY } = this.arc.right
      arc.setRight(new Line(fromX, fromY, toX, toY))
    }

    return treeNode
  }

  deepCopyAll() {
    let copy = this.deepCopy()
    if (this.left) {
      let left = this.left.deepCopyAll()
      copy.left = left
      left.parent = copy
    }

    if (this.right) {
      let right = this.right.deepCopyAll()
      copy.right = right
      right.parent = copy
    }
    return copy
  }

  getAllNode(treeNodes) {
    treeNodes.push(this)
    if (this.left) {
      this.left.getAllNode(treeNodes)
    }

    if (this.right) {
      this.right.getAllNode(treeNodes)
    }

    return treeNodes;
  }

  updateRightChildX(cur, x) {
    if (!cur) {
      return x
    }
    x = cur.updateRightChildX(cur.left, x)
    cur.setXY(x, cur.parent.y + 60)
   return cur.updateRightChildX(cur.right, x + Arc.R + 10) 
  }

  updateLeftChildX(cur, x) {
    if (!cur) {
      return x
    }

    x = cur.updateLeftChildX(cur.right, x) 
    cur.setXY(x, cur.parent.y + 60)
    return cur.updateLeftChildX(cur.left, x - Arc.R - 10)
  }

  updateChildY(cur) {
    if (!cur) {
      return
    }
    cur.setXY(cur.x, cur.parent.y + 60)
    cur.updateChildY(cur.left)
    cur.updateChildY(cur.right)
  }

  updateChildXY(rootX) {
    this.setXY(rootX, 70)
    this.updateChildY(this.left)
    this.updateChildY(this.right)
    this.updateLeftChildX(this.left, this.x - Arc.R - 10)
    this.updateRightChildX(this.right, this.x + Arc.R + 10)
  }


}